﻿Imports System
Imports System.Collections
Imports System.Net
Imports System.Net.Sockets
Imports System.Xml
Imports System.Timers
Imports System.IO

Imports VBWowClient_LIB.Foole.Crypt
Imports Foole.Utils
Imports Foole.WoW

Public Structure CharEquipment
    Public EntryID As UInt32
    Public Type As Byte
End Structure

Partial Class WorldServerClient
    Dim acount_data As Byte() = {&H78, &H1, &HBD, &H57, &HDB, &H96, &HAB, &H28, &H10, &H7D, &HE7, &H2B, &HFC, &H4, &HB5, &H93, &HB6, &HF3, &H48, &H14, &H23, &HD3, &H44, &HB2, &H4, &H3B, &H27, &HE7, &H85, &HFF, &HFF, &H8B, &H29, &HAE, &H82, &H4A, &H27, &HF, &H33, &H59, &HDD, &HAE, &H68, &H5D, &H36, &H50, &H54, &H15, &H9B, &H1F, &H32, &H9, &HCA, &HC7, &HA2, &H46, &H8, &H77, &H1D, &HE9, &H7E, &H96, &H6F, &H7E, &H93, &HA0, &H51, &H97, &H99, &HB2, &H4E, &H4D, &HA4, &H9D, &H66, &H2A, &HAF, &H64, &H94, &HAA, &H1D, &HF0, &H38, &H12, &H56, &HE0, &H59, &H72, &H84, &HDC, &H97, &H40, &H64, &HEC, &H10, &HFA, &HCB, &H47, &HE2, &H25, &H45, &H5D, &H9E, &H9A, &HEA, &H78, &H4, &H1B, &HCE, &HF8, &H24, &H90, &HC0, &H8F, &HA2, &H3E, &H1E, &HFD, &H83, &H6E, &H78, &H92, &H8F, &HA2, &H6A, &H4A, &HF3, &H80, &H6, &H4D, &H98, &H76, &H46, &H5D, &HD5, &H4D, &H51, &H22, &H33, &H76, &HF1, &H79, &H30, &HA2, &HCF, &H3, &HE2, &H7D, &H4F, &H5B, &H32, &H69, &H49, &H75, &HAA, &HE1, &H7, &H3D, &H8, &H63, &H4E, &HAB, &H3F, &HEF, &H3, &H15, &H37, &H30, &HD0, &HA3, &H54, &HF5, &H97, &HFE, &HF5, &H32, &H45, &HC7, &H9E, &H4F, &HD7, &H44, &H45, &HAE, &H5C, &H92, &H20, &H1, &H7F, &H49, &HFE, &H48, &HB5, &H91, &H8A, &H87, &H90, &HC4, &H7A, &H6A, &HE0, &H12, &H5D, &HF9, &H8, &H92, &H49, &HC5, &HB, &HAA, &H8E, &HA7, &H20, &H5F, &HCD, &HCA, &H9B, &H6F, &H80, &H7D, &H24, &HCD, &H74, &H61, &H41, &HB0, &H28, &H1F, &H4F, &HF5, &HF, &HA7, &HA3, &H59, &HA5, &H5E, &H7, &H3C, &H41, &HC1, &H8, &HFE, &H21, &HFB, &H1A, &H2A, &HE4, &HAE, &H62, &HE4, &H12, &HE2, &H66, &H55, &HAB, &H61, &HAC, &H4A, &HCD, &H2, &HA2, &HA6, &H63, &HEA, &H1E, &H84, &HFB, &HEF, &H10, &H18, &H1D, &HC5, &H6E, &HF4, &H1B, &H63, &HA3, &H4A, &H2F, &H23, &H9F, &H88, &H95, &H95, &H10, &H12, &HF1, &H4D, &H61, &H27, &HBE, &H8E, &HFA, &H5F, &HDB, &H33, &HCE, &H65, &H61, &H37, &HB6, &H84, &HFD, &HBF, &H9E, &HB1, &H54, &H57, &H2A, &H5A, &HB3, &HD, &H66, &H6F, &HFC, &HFE, &HF8, &HE8, &HF8, &HBD, &HAB, &H9A, &H13, &HE4, &H83, &H79, &HBC, &HA3, &H20, &HAC, &H57, &H3, &H95, &HC2, &H4C, &H49, &H47, &H4B, &HF, &HE1, &H50, &H8D, &H12, &HA0, &H5, &HD9, &H55, &HDF, &H88, &HCC, &HBA, &H6A, &HDD, &H2F, &H9E, &H3A, &H3D, &HF3, &HBE, &H46, &H9B, &HF7, &HEE, &H27, &HA, &H15, &HC1, &H1E, &H37, &H86, &H1F, &H90, &H2A, &HB9, &HD9, &HAF, &HCC, &HF2, &H78, &H3, &H17, &H92, &H32, &HF2, &H4, &H2E, &HB5, &HCA, &HA3, &HB5, &H13, &HC1, &H72, &H9E, &H88, &HFA, &H11, &H2A, &H8D, &HEE, &HA1, &H29, &HE, &H8D, &H8F, &HED, &HC6, &H2C, &H42, &HCC, &H1A, &H9A, &HB2, &HCE, &H2E, &H38, &H86, &HB4, &H96, &H11, &HE6, &H6A, &H6B, &H63, &HDB, &HF0, &H9E, &H8B, &H64, &H30, &H80, &H25, &H85, &HF7, &H3C, &HB6, &HF, &HBC, &HEA, &H20, &H12, &HC3, &H5E, &H62, &HB9, &H58, &HE6, &HD, &HFE, &HDC, &HD4, &H5, &HEB, &H2A, &HAD, &H2A, &HF3, &HE8, &HA4, &H84, &HF6, &HC3, &H98, &HD, &H69, &H87, &HAF, &HF8, &H62, &HDB, &H8B, &H5E, &H17, &HD4, &HC8, &HA2, &H3B, &HCF, &H7D, &H1F, &HC6, &HF4, &H1A, &H9D, &H8E, &H2B, &HA7, &H5, &H52, &H2B, &H13, &HAF, &H48, &H65, &H52, &H31, &HEF, &H69, &HD4, &H19, &H5F, &H1F, &H6, &H97, &H57, &H59, &H90, &H95, &H5D, &H6, &H2D, &H4D, &HBF, &H2C, &H58, &H6A, &H96, &HC1, &HA, &H7B, &HE8, &H53, &HD4, &HC3, &H95, &H75, &HD1, &H7C, &H16, &H75, &HD5, &HB8, &H80, &H6E, &HC, &H5F, &H0, &HB4, &H99, &HE7, &H11, &H6D, &H43, &H31, &H4D, &HC5, &HEE, &H51, &HC, &H69, &H4D, &H5F, &HC0, &HC, &H4E, &H2F, &HC1, &H6, &HEB, &HC, &HB2, &H9C, &H70, &H47, &H4C, &H57, &H4D, &HDB, &H9A, &H9D, &HA0, &H1D, &H42, &HC, &H94, &HB0, &H4E, &H28, &H38, &HA6, &H75, &H11, &H87, &H84, &H5A, &H52, &H63, &H63, &HC7, &HE5, &H0, &H47, &HFC, &H8E, &H25, &H9E, &H27, &HAC, &H2E, &H70, &H7C, &HE7, &HA0, &H16, &H3, &H13, &H91, &H5F, &H21, &HCC, &H28, &H3B, &H16, &H14, &HCE, &H51, &H45, &H46, &H7D, &HEE, &H19, &H2E, &HB1, &H37, &H91, &H33, &HB4, &HA6, &H6F, &HA5, &H47, &HDB, &H1, &H80, &HC3, &H9D, &HF2, &H8E, &HB6, &HBB, &H15, &HB6, &H2C, &H3B, &H35, &HD3, &H11, &HDE, &H1B, &H29, &H58, &H3D, &HC9, &H86, &H95, &HDD, &H53, &HB8, &H55, &HAD, &H64, &HD3, &H21, &HE0, &HAE, &H1C, &H9E, &HE, &H90, &HD6, &HCF, &H73, &HFC, &HD4, &HFE, &H29, &H7C, &H48, &HCD, &HE7, &HC8, &HC1, &H34, &H7, &HDA, &H63, &H38, &HB4, &H3A, &HC5, &H78, &H8B, &H99, &HED, &H31, &HC9, &HAE, &HBA, &H33, &H7C, &HE0, &HC0, &H26, &H6C, &H33, &HAD, &H6B, &HA0, &H7B, &H50, &HE2, &H55, &H89, &HCE, &H17, &H65, &HA9, &H97, &H1A, &HC9, &HC, &HF5, &H60, &H99, &H5E, &H55, &H3, &HAD, &H88, &H95, &H98, &H31, &H8A, &H47, &HE0, &H37, &H9A, &H6E, &H80, &HF3, &HC7, &H29, &HF2, &H1C, &HF8, &HD4, &HD9, &H1E, &HAC, &H59, &H8A, &H1B, &HAE, &HC7, &HAD, &HE1, &HB6, &H3A, &HF, &HA1, &H43, &H3B, &H86, &HA5, &H27, &HA6, &H29, &H1C, &H59, &H58, &H6A, &H69, &H18, &HA9, &H2, &HCA, &HD5, &H39, &H56, &H59, &H57, &HC0, &H4C, &HBE, &H3E, &HAC, &HFC, &H8E, &HA7, &H91, &H8E, &H17, &HBB, &H22, &HA7, &H0, &H92, &H49, &H80, &H1C, &H29, &HE9, &H99, &HA9, &HE7, &H39, &H9A, &HDB, &HAA, &H33, &H17, &H22, &H22, &H98, &H1E, &HAD, &HA7, &HC, &HF8, &H64, &H44, &HA7, &H80, &H2E, &H49, &H46, &H2E, &H13, &H9F, &H3, &HEF, &HD2, &H84, &H38, &H16, &HEF, &HCD, &HCA, &H11, &HCA, &HCA, &HCC, &HC8, &H53, &H39, &H27, &HAC, &HF7, &H84, &H1F, &H7B, &H42, &HCB, &HB7, &H57, &HEE, &H96, &HB6, &HAF, &H84, &HD0, &H86, &HA1, &H77, &HAE, &H84, &HCD, &H9E, &HD0, &HB0, &HC6, &HB5, &HE5, &H69, &HCF, &HB2, &H2A, &H13, &HA9, &HB9, &H56, &HDC, &HE9, &HD8, &HF1, &H7B, &H51, &H21, &H41, &HFF, &HC2, &H3E, &HC3, &H3E, &HC2, &H85, &H2, &HF6, &HDB, &HFC, &H1, &HD7, &H6C, &HBF, &H21, &H76, &H15, &HEA, &HFC, &H8B, &H18, &HF8, &H1D, &HCE, &H65, &H84, &HAE, &H44, &H8, &H38, &H84, &HE1, &HEE, &H61, &H38, &HBC, &HBE, &H82, &H98, &H3B, &H83, &HBF, &H15, &HD8, &H3B, &H88, &HBD, &H68, &H20, &H9F, &HCC, &H9E, &H6A, &H5B, &H52, &H6B, &HA8, &HAC, &HBD, &HDD, &HB8, &H48, &HFE, &H7A, &HD7, &H89, &HE7, &H5B, &HBF, &H36, &H5F, &H30, &H33, &HF3, &H2D, &HA3, &HF9, &HAE, &H29, &HB3, &H4F, &HDD, &H40, &HD6, &H12, &H81, &HA5, &H39, &H5E, &HE4, &H29, &H6F, &HFC, &H9D, &H5A, &HA4, &HD, &H41, &H33, &H2A, &H6F, &H9B, &H6A, &H52, &H2F, &H1F, &H9F, &H84, &H34, &H7A, &HC7, &H8D, &H32, &HF5, &HF5, &H2D, &HCE, &HB2, &H29, &HEF, &HE4, &H46, &H4B, &H85, &H8E, &H56, &HC5, &H74, &HC9, &H36, &HA2, &H58, &HA2, &HFB, &H8D, &HFB, &H5E, &H68, &H53, &H24, &H88, &HF4, &HE9, &H92, &H12, &HA8, &H54, &H15, &HF9, &H6C, &H56, &H93, &HB8, &H6D, &HB4, &H91, &H67, &H74, &H6E, &HBB, &HE9, &H58, &HD7, &HD5, &H59, &HED, &H74, &HCB, &HA1, &HAA, &H37, &HD6, &H9, &H37, &HA7, &HA4, &H93, &H2F, &H27, &HA3, &H13, &H84, &H3, &HC4, &H64, &H45, &H32, &HC5, &H54, &HA5, &HE7, &H7, &H35, &H60, &HF8, &H67, &HD0, &HA4, &H8B, &HDF, &HF7, &H4E, &H6D, &H76, &H61, &H42, &H30, &HF6, &H11, &H82, &HDA, &H3A, &H6F, &H1A, &HBE, &H4F, &H85, &HB4, &H27, &HDB, &H3E, &HFC, &HB4, &HEA, &HA0, &H62, &HE2, &H7A, &HFB, &H78, &HAD, &HDE, &H80, &H6F, &H6F, &HEA, &HCD, &HC0, &HFC, &H52, &HDF, &HAB, &H91, &HE, &H6F, &H1B, &H9, &HAE, &H14, &HAF, &HF4, &HBC, &HFF, &H60, &H4D, &H9F, &H6F, &H1B, &H9, &H98, &HFB, &H9B, &HD6, &HF4, &HF5, &HB6, &H91, &H4E, &H6F, &H1B, &H9, &HC8, &HCF, &HFF, &H1E, &HBE, &H7F, &H1, &H34, &H99, &H2, &H24}

    Private Sub Handle_AuthRequest(ByVal wr As WoWReader)
        BoogieCore.Log(LogType.System, "WS: Recieved Authentication Challenge: Sending out response")
        ServerSeed = wr.ReadUInt32()
            ClientSeed = (UInt32)random.Next()

        Sha1Hash(sha = New Sha1Hash())
        sha.Update(mUsername)
        sha.Update(0) ' t
        sha.Update(ClientSeed)
        sha.Update(ServerSeed)
        sha.Update(Key)
            byte[] Digest = sha.Final()

        WoWWriter(ww = New WoWWriter(OpCode.CMSG_AUTH_SESSION))
        ww.Write(BoogieCore.configFile.ReadInteger("WoW", "Build"))
            ww.Write((UInt32)0)
        ww.Write(mUsername)
        ww.Write(ClientSeed)
        ww.Write(Digest)

        StreamReader(SR)
        WoWWriter(Buffer = New WoWWriter())
        SR = File.OpenText("Addons.txt")
            string Line = SR.ReadLine()

            while (Line != null)
            {
                string[] Fields = new string[3]
                string Name = null
            UInt64(Checksum = 0)
                byte unk = &H0

                Fields = Line.Split(':')
                Name = Fields[0]
                Checksum = UInt64.Parse(Fields[1])
            'unk = (Fields[2].ToCharArray())[0]

                if (Name != null && Checksum > 0)
                {
                Buffer.Write(Name)
                Buffer.Write(Checksum)
                Buffer.Write(unk)

                'BoogieCore.Log("Adding addon {0} with the checksum {1}", Name, Checksum)
                }

                Line = SR.ReadLine()
            }

                SR.Close()

            byte[] buffer2 = Foole.Utils.Compression.Compress(buffer.ToArray())
            UInt32 Size = (UInt32)buffer.ToArray().Length

                ww.Write(Size)
                ww.Write(buffer2)

                Send(ww)

                mCrypt.Init(Key)
    End Sub

    Private Sub Handle_AuthResponse(ByVal wr As WoWReader)
            byte error = wr.ReadByte()
            if (error != &H0C)
            {
                BoogieCore.Log(LogType.Error, "WS: Authentication Failed: Error = {0}", error)
            Return
            }
            BoogieCore.Log(LogType.System, "WS: Authentication Successful!")

            BoogieCore.Log(LogType.System, "WS: Requesting Character List...")

            WoWWriter(ww = New WoWWriter(OpCode.CMSG_CHAR_ENUM))
            Send(ww.ToArray())
            aTimer.Enabled = True
    End Sub

    Private Sub Handle_CharEnum(ByVal wr As WoWReader)
        BoogieCore.Log(LogType.NeworkComms, "WS: Recieved Character List..")
            count as byte = wr.ReadByte()

        characterList = New Character(count)


        For i = 0 To count
            characterList([i].GUID = wr.ReadUInt64())
            characterList([i].Name = wr.ReadString())
            characterList([i].Race = wr.ReadByte())
            characterList([i].Class = wr.ReadByte())
            characterList([i].Gender = wr.ReadByte())
            characterList([i].Skin = wr.ReadByte())
            characterList([i].Face = wr.ReadByte())
            characterList([i].HairStyle = wr.ReadByte())
            characterList([i].HairColor = wr.ReadByte())
            characterList([i].FacialHair = wr.ReadByte())
            characterList([i].Level = wr.ReadByte())
            characterList([i].ZoneID = wr.ReadUInt32())
            characterList([i].MapID = wr.ReadUInt32())
            characterList([i].X = wr.ReadFloat())
            characterList([i].Y = wr.ReadFloat())
            characterList([i].Z = wr.ReadFloat())
            characterList([i].Guild = wr.ReadUInt32())
            characterList([i].Unk = wr.ReadUInt32())
            characterList([i].RestState = wr.ReadByte())
            characterList([i].PetInfoID = wr.ReadUInt32())
            characterList([i].PetLevel = wr.ReadUInt32())
            characterList([i].PetFamilyID = wr.ReadUInt32())

                CharEquipment[] equip = new CharEquipment[20]

            For x = 0 To 20
                equip([x].EntryID = wr.ReadUInt32())
                equip([x].Type = wr.ReadByte())
                wr.ReadUInt32() ' enchant (2.4 patch)
            Next

            characterList([i].Equipment = equip)
        Next

        BoogieCore.Log(LogType.NeworkComms, "{0} characters in total.", characterList.Length)

            String defaultChar = BoogieCore.configFile.ReadString("Connection", "DefaultChar")
        If (Not defaultChar = "") Then
                for each (c as Character in characterList)
                If (c.Name.ToLower() = defaultChar.ToLower()) Then
                    BoogieCore.Log(LogType.System, "Defaulting to Character {0}", defaultChar)
                    BoogieCore.WorldServerClient.LoginChar(c.GUID)
                    Return
                End If
                If (count < 1) Then
                name as string = RandomString(6, false)
                    BoogieCore.Log(LogType.System, "Auto-Generating Human Character with the name {0}", name)
                    WoWWriter(ww = New WoWWriter(OpCode.CMSG_CHAR_CREATE))
                    ww.Write(name)
                ww.Write((byte)1) ' race - human
                ww.Write((byte)1) ' class - warrior
                ww.Write((byte)0) ' gender - male
                ww.Write((byte)1) ' skin
                ww.Write((byte)1) ' face
                ww.Write((byte)1) ' hair style
                ww.Write((byte)1) ' hair color
                ww.Write((byte)1) ' facial hair
                ww.Write((byte)1) ' outfit id
                    Send(ww.ToArray())
                    ww = New WoWWriter(OpCode.CMSG_CHAR_ENUM)
                    Send(ww.ToArray())
                    Return
                End If

                If (count = 1) Then
                BoogieCore.Log(LogType.System, "Defaulting to Character {0}", characterList[0].Name)
                BoogieCore.WorldServerClient.LoginChar(characterList[0].GUID)
                    Return
                End If
            e as Events = new Event(EventType.EVENT_CHAR_LIST, Time.GetTime(), characterList)
                BoogieCore.Event(e)
    End Sub

    Public Sub WorldZone(ByVal guid As UInt64)
        WoWWriter(ww = New WoWWriter(OpCode.CMSG_PLAYER_LOGIN))
        ww.Write(guid)
        Send(ww.ToArray())

        ww = New WoWWriter(OpCode.CMSG_UPDATE_ACCOUNT_DATA)
            ww.Write((UInt32)7)
            ww.Write((UInt32)5144)
        ww.Write(account_data)
        Send(ww.ToArray())

        ww = New WoWWriter(OpCode.CMSG_NAME_QUERY)
        ww.Write(guid)
        Send(ww.ToArray())

        ww = New WoWWriter(OpCode.CMSG_SET_ACTIVE_MOVER)
        ww.Write(guid)
        Send(ww.ToArray())
    End Sub

    Public Sub LoginChar(ByVal guid As UInt64)
        For Each (c as Character in characterList)
            If (c.GUID = guid) Then
                BoogieCore.World.setPlayer(c.MapID, New WoWGuid(guid))
                BoogieCore.Player.setPlayer(c)
            End If
        Next

        characterList = Nothing ' No longer needed!

        WoWWriter(ww = New WoWWriter(OpCode.CMSG_PLAYER_LOGIN))
        ww.Write(guid)
        Send(ww.ToArray())

        ww = New WoWWriter(OpCode.CMSG_UPDATE_ACCOUNT_DATA)
            ww.Write((UInt32)7)
            ww.Write((UInt32)5144)
        ww.Write(account_data)
        Send(ww.ToArray())

        ww = New WoWWriter(OpCode.CMSG_NAME_QUERY)
        ww.Write(guid)
        Send(ww.ToArray())

        ww = New WoWWriter(OpCode.CMSG_SET_ACTIVE_MOVER)
        ww.Write(guid)
        Send(ww.ToArray())
    End Sub
End Class
